package com.yyfax.pay.quartz.model.vo;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;

import com.yyfax.framework.model.BasePO;
import com.yyfax.pay.depository.domain.FuiouQueryTask;
import com.yyfax.pay.order.model.po.NotifyTaskPO;
import com.yyfax.pay.order.model.po.QueryTaskPO;

/**
 * 定义一 个动态的 JOB
 *
 * @author admin
 */
public class DynamicJobVO {

	public static final String ORDER_KEY = "O_";

	// Job class
	private Class<? extends Job> target;

	// cron expression
	private String cronExpression;

	private String jobGroup = Scheduler.DEFAULT_GROUP;

	// Must unique
	private String jobName;

	private transient TriggerKey triggerKey;

	private transient JobDetail jobDetail;

	// default
	public DynamicJobVO() {
	}

	/**
	 * @param task
	 */
	public DynamicJobVO(QueryTaskPO task) {
		this.jobName = "QT-" + task.getTradeOrderId() + "-" + task.getType();
	}

	/**
	 * @param task
	 */
	public DynamicJobVO(NotifyTaskPO task) {
		this.jobName = "NT-" + task.getTradeOrderId() + "-" + task.getType();
	}

	/**
	 * @param task
	 */
	public DynamicJobVO(FuiouQueryTask task) {
		this.jobName = "NT-" + task.getBusiId() + "-" + task.getType();
	}

	public Class<? extends Job> target() {
		return target;
	}

	public DynamicJobVO target(Class<? extends Job> target) {
		this.target = target;
		return this;
	}

	public DynamicJobVO cronExpression(String cronExpression) {
		this.cronExpression = cronExpression;
		return this;
	}

	public String jobGroup() {
		return jobGroup;
	}

	public DynamicJobVO jobGroup(String jobGroup) {
		this.jobGroup = jobGroup;
		return this;
	}

	public String jobName() {
		return jobName;
	}

	public DynamicJobVO jobName(String jobName) {
		this.jobName = jobName;
		return this;
	}

	public TriggerKey triggerKey() {
		if (triggerKey == null) {
			triggerKey = TriggerKey.triggerKey(this.jobName, this.jobGroup);
		}
		return triggerKey;
	}

	public JobDetail jobDetail() {
		if (jobDetail == null) {
			jobDetail = JobBuilder.newJob(target).withIdentity(this.jobName, this.jobGroup).storeDurably(true).build();
		}
		return jobDetail;
	}

	public DynamicJobVO addJobData(String key, Object value) {
		final JobDetail detail = jobDetail();
		final JobDataMap jobDataMap = detail.getJobDataMap();
		jobDataMap.put(key, value);
		return this;
	}

	public DynamicJobVO addOrderData(BasePO po) {
		return addJobData(ORDER_KEY, po);
	}

	@SuppressWarnings("unchecked")
	public <PO extends BasePO> PO getOrderData() {
		final JobDetail detail = jobDetail();
		final JobDataMap jobDataMap = detail.getJobDataMap();
		Object object = jobDataMap.get(ORDER_KEY);
		if (object == null) {
			return null;
		}
		return (PO) object;
	}

	public String cronExpression() {
		return this.cronExpression;
	}

	public CronTrigger cronTrigger() {
		final CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(this.cronExpression);
		return TriggerBuilder.newTrigger().withIdentity(triggerKey()).withSchedule(cronScheduleBuilder).build();
	}

	@Override
	public String toString() {
		return "{" + "cronExpression='" + cronExpression + '\'' + ", jobGroup='" + jobGroup + '\'' + ", jobName='" + jobName + '\'' + '}';
	}
}